/*
 * Copyright 2012-2014 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell.suggest;

import finbudget.client.general.NodeSuggestionOracle;
import finbudget.client.ui.table.Record;
import finbudgettable.client.ui.grid.filter.Filter;
import finbudgettable.client.ui.grid.filter.FilterResolver;
import finbudgettable.client.ui.grid.filter.FilterResolverRepository;

public class ContainSuggestFilter implements Filter {

    private final String fieldName;
    /**
     * Raw filter value
     */
    private final String value;
    private final NodeSuggestionOracle oracle;
    private final String[] valuesToTest;

    public ContainSuggestFilter(String fieldName, String value, NodeSuggestionOracle oracle) {
        this.fieldName = fieldName;
        this.value = value == null ? "" : value.trim().toLowerCase();
        this.oracle = oracle;

        valuesToTest = ContainSuggestFilter.getValuesToTestFromString(this.value);
    }

    public static String[] getValuesToTestFromString(String value) {
        String[] valuesToTest = value.split(",");
        for (int i = 0; i < valuesToTest.length; i++) {
        	String test = valuesToTest[i];
        	if (test != null) {
        		test = test.trim();
        		if (test.isEmpty()) {
        			test = null;
        		}
        		valuesToTest[i] = test;
        	}
        }
        return valuesToTest;
    }

    @Override
    public boolean match(Record rec) {
        String fieldValue = rec.getValueString(fieldName);
        if (fieldValue != null) {
        	return ContainSuggestFilter.isValueMatchesToTestValues(oracle.getItemNameByKey(fieldValue), valuesToTest);
        }
        return false;
    }

    public static boolean isValueMatchesToTestValues(String itemValue, String[] valuesToTest) {
    	if (itemValue != null) {
    		itemValue = itemValue.toLowerCase();
    		// OR logic
    		for (String test : valuesToTest) {
    			if (test != null) {
    				if (itemValue.contains(test)) {
    					return true;
    				}
    			}
    		}
    	}
    	return false;
    }

    static {
        FilterResolverRepository.put(
                ContainSuggestFilter.class,
                new FilterResolver<ContainSuggestFilter>() {
                    @Override
                    public String resolve(ContainSuggestFilter filter) {
                        return SuggestFilterPanel.STRINGS.contains(filter.value);
                    }
                }
        );
    }

    public String getValue() {
        return value;
    }

}
